// 设计一个电路，使用时序逻辑对一个单bit信号进行毛刺滤
// 除操作。高电平或者低电平宽度小于4个时钟周期的为毛


//1.电平计数法
module filter(
           input wire sys_clk,
           input wire sys_rst_n,
           input wire data_in,

           output reg data_out
       );

reg [1: 0] cnt_low, cnt_high;

always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if (!sys_rst_n)
			begin
				cnt_high <= 2'd0;
			end
		else if (!data_in )
			begin
				cnt_high <= 2'd0;
			end
		else if (data_in && cnt_high != 2'd3)
			cnt_high <= cnt_high + 1'b1;
		else
			cnt_high <= cnt_high;
	end

always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if (!sys_rst_n)
			begin
				cnt_low <= 2'd0;
			end
		else if (data_in)
			begin
				cnt_low <= 2'd0;
			end
		else if (!data_in && !( & cnt_low))
			cnt_low <= cnt_low + 1'b1;
		else
			cnt_low <= cnt_low;
	end

always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if (!sys_rst_n)
			data_out <= 1'b0;
		else if ( & cnt_high && data_in)
			data_out <= 1'b1;
		else if ( & cnt_low && !data_in)
			data_out <= 1'b0;
		else
			data_out <= data_out;
	end
endmodule


//脉冲计数器
module filter2(
    input wire sys_clk,
    input wire sys_rst_n,
    input wire data_in,

    output reg data_out
);

reg [1: 0] cnt;
reg data_in_reg;

wire podge, nedge;

always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if (!sys_rst_n)
			data_in_reg <= 1'b0;
		else
			data_in_reg <= data_in;
	end

assign podge = !data_in_reg && data_in;
assign nedge = data_in_reg && !data_in;

always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if (!sys_rst_n)
			cnt <= 2'd0;
		else if (podge | nedge)
			cnt <= 2'd0;
		else if (!podge && !nedge)
			//脉冲本来就会晚一个周期，故判断为2
			cnt <= cnt + 1'b1;
		else
			cnt <= cnt;
	end

always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if (!sys_rst_n)
			data_out <= 1'b0;
		else if ( cnt == 2'd2)
				data_out <= data_in_reg;
		else
			data_out <= data_out;
	end

endmodule

